#ifndef _AGORA_GLOBALS_H
#define _AGORA_GLOBALS_H

#if defined(_WIN32) || defined(_WIN64)
	#include <Windows.h>
#else
	#include <unistd.h>
	#include <pthread.h>
#endif

#include <vector>

#include "types.h"
  
struct agr_user;
struct agr_file;  
struct agr_chunk;
 
struct IPv4
{
    u8 b1, b2, b3, b4;
};

struct agr_user{
	char username[256];
	IPv4 ip;
	u64 ID;

	SOCKET socket;

	std::vector<agr_file*> filesList;
};
  
struct agr_file{
	agr_user *owner;

	char nameMD5[32];
	long fID;
	char path[1024];
	FILE *handle;
	u64 handlerID;
	u64 size;

	std::vector<agr_chunk*> fileChunks;


#if defined(_WIN32) || defined(_WIN64)
		CRITICAL_SECTION csLock;

		void init(){
			InitializeCriticalSection(&csLock);
		};

		void destroy(){
			DeleteCriticalSection(&csLock);
		};

		void lock(){
			EnterCriticalSection(&csLock);
		};

		void unlock(){
			LeaveCriticalSection(&csLock);
		};
	
#else

		pthread_mutex_t csLock; 

		void init(){
			csLock = PTHREAD_MUTEX_INITIALIZER;
		};

		void destroy(){
			pthread_mutex_destroy(&csLock);
		};

		void lock(){
			pthread_mutex_lock(&csLock);
		};

		void unlock(){
			pthread_mutex_unlock(&csLock);
		};
	
#endif
};

enum chunk_status{
	CHUNK_EMPTY = 0,
	CHUNK_DOWNLOADING,
	CHUNK_COMPLETE,
	CHUNK_CORRUPT,
};

struct agr_chunk{
  agr_file *file;
  
  chunk_status status;
  u64 offset;
  u64 size;
  u64 crc32;
  u8 percent;

  u8 *data;
};
  
#endif
